package com.wayhome.srpingbootmybatis.boc.util;

import lombok.extern.slf4j.Slf4j;

import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @ProjectName: busPay
 * @Package: com.yada.buspay.model.util
 * @ClassName: SHA256WithRSAUtil
 * @Author: lyh
 * @Date: 2020/7/23 0023 10:26
 * @Version: 1.0
 */
@Slf4j
public class SHA256WithRSAUtil {
    private static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
    public static final String ENCODE_ALGORITHM = "SHA-256";

    /**
     * 解码PublicKey
     * @param key
     * @return
     */
    public static PublicKey getPublicKey(String key) {
        try {
            byte[] byteKey = Base64.getDecoder().decode(key);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            return keyFactory.generatePublic(x509EncodedKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 解码PrivateKey
     * @param key
     * @return
     */
    public static PrivateKey getPrivateKey(String key) {
        try {
            byte[] byteKey = Base64.getDecoder().decode(key);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(byteKey);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Map<String,String> getModulesAndExponent(String PUBKEY_TEXT) throws Exception {
        Map<String,String> res = new HashMap<>();
        try {
            // 解密由base64编码的公钥,并构造X509EncodedKeySpec对象
            X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(
            		org.apache.commons.codec.binary.Base64.decodeBase64(PUBKEY_TEXT));
            // RSA算法
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            // 取公钥匙对象
            RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(bobPubKeySpec);

            res.put("modules",pubKey.getModulus().toString(16));
            res.put("PE","0x"+pubKey.getPublicExponent().toString(16));
//            System.out.println("modules: 0x" + pubKey.getModulus().toString(16));
//            System.out.println("publicExponent: 0x" + pubKey.getPublicExponent().toString(16));
        }catch(Exception e) {
            e.getMessage();
            res.put("modules",e.getMessage());
            res.put("PE",e.getMessage());
        }
        return res;
    }

    /**
     * 签名
     * @param key	私钥
     * @param requestData	请求参数
     * @return
     */
    public static String sign(String key, String requestData){
        String signature = null;
        byte[] signed = null;
        try {
            PrivateKey privateKey = getPrivateKey(key);
            Signature Sign = Signature.getInstance(SIGNATURE_ALGORITHM);
            Sign.initSign(privateKey);
            Sign.update(requestData.getBytes());
            signed = Sign.sign();
            signature = Base64.getEncoder().encodeToString(signed);
            log.info("==========>中行生成签名数据，代签串：{},签名后数据sign：{}", requestData, signature);
        } catch (Exception e) {
            log.info("发起中行请求签名时出现错误：{}", e.getMessage(), e);
        }

        return signature;
    }

    /**
     * 验签
     * @param key	公钥
     * @param requestData	请求参数
     * @param signature	签名
     * @return
     */
    public static boolean verifySign(String key, String requestData, String signature){
        boolean verifySignSuccess = false;
        try {
            PublicKey publicKey = getPublicKey(key);

            Signature verifySign = Signature.getInstance(SIGNATURE_ALGORITHM);
            verifySign.initVerify(publicKey);
            verifySign.update(requestData.getBytes());

            verifySignSuccess = verifySign.verify(Base64.getDecoder().decode(signature));
            System.out.println("==========>中行签名验签结果："+verifySignSuccess);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return verifySignSuccess;
    }


    public static void main(String[] args){

//        String PEStr = "010001";
//        String newStr = "";
//        if(PEStr.length()>=0 && PEStr.length()<=9){
//            newStr="00" + PEStr.length() + PEStr;
//        }else if(PEStr.length()>=10 && PEStr.length()<=99){
//            newStr="0"+PEStr.length()+PEStr;
//        }else{
//            newStr=PEStr.length()+PEStr;
//        }
//        System.out.println(PEStr.length());
//        System.out.println(newStr);


//        RSAPublicKey getPublicKey = (RSAPublicKey)getPublicKey(PUBLIC_KEY_NAME);
        RSAPublicKey getPublicKey = (RSAPublicKey)getPublicKey("24663EA498FA15D29ACD3AC74C03BDB8E136F15313CFF331775F0E91E7E6B3CB4970ABE3E8615E2742EAE4451620F8232E5945E83855D1DE96CCA822015D34A46ED37E02462BB83C769E2F95BD0D7293A5E346626BD1292088206E0DD2595B320CC51FFA5AB6A47E6CC80A5323F049DA718B9B5816B25121C9FEBFB53419BA537E6AC3E8A47C038886BB01BBE63926F11F26B3517ED9DDB4559BA6E9FC9E1ED81D5A42AF680531BA10065877E10F5A74D22950C937D8A2325ACF89AAE1F34DC110C421363465E314D1129A6062A0F0E4B1B5141D05AF911D866EF06E4D00C5EB9FE096090064459C1CF5646F13BF69EC6B2B6D5952F0FF77CAA36157C5A3C5B6");
        System.out.println(getPublicKey);
        System.out.println("PM10:"+getPublicKey.getModulus().toString(10));
        System.out.println("PE10:"+getPublicKey.getPublicExponent().toString(10));
        System.out.println("PM16:"+getPublicKey.getModulus().toString(16));
        System.out.println("PE16:"+getPublicKey.getPublicExponent().toString(16));

//        try {
//            Map<String,String> a = SHA256WithRSAUtil.getModulesAndExponent(PUBLIC_KEY_NAME);
//            System.out.println("modules==="+a.get("modules"));
//            System.out.println("PE==="+a.get("PE"));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }



    }

//    public static String encrypt( String str, String publicKey ) throws Exception{
//        //base64编码的公钥
//        byte[] decoded = Base64.decodeBase64(publicKey);
//        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//        //RSA加密
//        Cipher cipher = Cipher.getInstance("RSA");
//        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
//        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
//        return outStr;
//    }
}
